home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / bind493a.zip / res / res_send.c < prev    next >
C/C++ Source or Header  |  1995-12-03  |  20KB  |  766 lines

  1. /*
  2.  * ++Copyright++ 1985, 1989, 1993
  3.  * -
  4.  * Copyright (c) 1985, 1989, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)res_send.c    8.1 (Berkeley) 6/4/93";
  58. static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61.     /* change this to "0"
  62.      * if you talk to a lot
  63.      * of multi-homed SunOS
  64.      * ("broken") name servers.
  65.      */
  66. #define    CHECK_SRVR_ADDR    1    /* XXX - should be in options.h */
  67.  
  68. /*
  69.  * Send query to name server and wait for reply.
  70.  */
  71.  
  72. #include <sys/param.h>
  73. #include <sys/time.h>
  74. #include <sys/socket.h>
  75. #include <sys/uio.h>
  76. #include <netinet/in.h>
  77. #include <arpa/nameser.h>
  78. #include <arpa/inet.h>
  79.  
  80. #include <stdio.h>
  81. #include <netdb.h>
  82. #include <errno.h>
  83. #include <resolv.h>
  84. #if defined(BSD) && (BSD >= 199306)
  85. # include <stdlib.h>
  86. # include <string.h>
  87. # include <unistd.h>
  88. #else
  89. # include "../conf/portability.h"
  90. #endif
  91.  
  92. #if defined(USE_OPTIONS_H)
  93. # include <../conf/options.h>
  94. #endif
  95.  
  96. void _res_close __P((void));
  97.  
  98. static int s = -1;    /* socket used for communications */
  99. static int connected = 0;    /* is the socket connected */
  100. static int vc = 0;    /* is the socket a virtual ciruit? */
  101.  
  102. #ifndef FD_SET
  103. /* XXX - should be in portability.h */
  104. #define    NFDBITS        32
  105. #define    FD_SETSIZE    32
  106. #define    FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  107. #define    FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  108. #define    FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  109. #define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  110. #endif
  111.  
  112. /* XXX - this should be done in portability.h */
  113. #if (defined(BSD) && (BSD >= 199103)) || defined(linux)
  114. # define CAN_RECONNECT 1
  115. #else
  116. # define CAN_RECONNECT 0
  117. #endif
  118.  
  119. #ifndef DEBUG
  120. #   define Dprint(cond, args) /*empty*/
  121. #   define DprintQ(cond, args, query, size) /*empty*/
  122. #   define Aerror(file, string, error, address) /*empty*/
  123. #   define Perror(file, string, error) /*empty*/
  124. #else
  125. #   define Dprint(cond, args) if (cond) {fprintf args;} else {}
  126. #   define DprintQ(cond, args, query, size) if (cond) {\
  127.             fprintf args;\
  128.             __fp_nquery(query, size, stdout);\
  129.         } else {}
  130.     static void
  131.     Aerror(file, string, error, address)
  132.     FILE *file;
  133.     char *string;
  134.     int error;
  135.     struct sockaddr_in address;
  136.     {
  137.     int save = errno;
  138.  
  139.     if (_res.options & RES_DEBUG) {
  140.         fprintf(file, "res_send: %s ([%s].%u): %s\n",
  141.             string,
  142.             inet_ntoa(address.sin_addr),
  143.             ntohs(address.sin_port),
  144.             strerror(error));
  145.     }
  146.     errno = save;
  147.     }
  148.     static void
  149.     Perror(file, string, error)
  150.     FILE *file;
  151.     char *string;
  152.     int error;
  153.     {
  154.     int save = errno;
  155.  
  156.     if (_res.options & RES_DEBUG) {
  157.         fprintf(file, "res_send: %s: %s\n",
  158.             string, strerror(error));
  159.     }
  160.     errno = save;
  161.     }
  162. #endif
  163.  
  164. static res_send_qhook Qhook = NULL;
  165. static res_send_rhook Rhook = NULL;
  166.  
  167. void
  168. res_send_setqhook(hook)
  169.     res_send_qhook hook;
  170. {
  171.  
  172.     Qhook = hook;
  173. }
  174.  
  175. void
  176. res_send_setrhook(hook)
  177.     res_send_rhook hook;
  178. {
  179.  
  180.     Rhook = hook;
  181. }
  182.  
  183. /* int
  184.  * res_isourserver(ina)
  185.  *    looks up "ina" in _res.ns_addr_list[]
  186.  * returns:
  187.  *    0  : not found
  188.  *    >0 : found
  189.  * author:
  190.  *    paul vixie, 29may94
  191.  */
  192. int
  193. res_isourserver(inp)
  194.     const struct sockaddr_in *inp;
  195. {
  196.     struct sockaddr_in ina;
  197.     register int ns, ret;
  198.  
  199.     ina = *inp;
  200.     ret = 0;
  201.     for (ns = 0;  ns < _res.nscount;  ns++) {
  202.         register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
  203.  
  204.         if (srv->sin_family == ina.sin_family &&
  205.             srv->sin_port == ina.sin_port &&
  206.             (srv->sin_addr.s_addr == INADDR_ANY ||
  207.              srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
  208.             ret++;
  209.             break;
  210.         }
  211.     }
  212.     return (ret);
  213. }
  214.  
  215. /* int
  216.  * res_nameinquery(name, type, class, buf, eom)
  217.  *    look for (name,type,class) in the query section of packet (buf,eom)
  218.  * returns:
  219.  *    -1 : format error
  220.  *    0  : not found
  221.  *    >0 : found
  222.  * author:
  223.  *    paul vixie, 29may94
  224.  */
  225. int
  226. res_nameinquery(name, type, class, buf, eom)
  227.     const char *name;
  228.     register int type, class;
  229.     const u_char *buf, *eom;
  230. {
  231.     register const u_char *cp = buf + HFIXEDSZ;
  232.     int qdcount = ntohs(((HEADER*)buf)->qdcount);
  233.  
  234.     while (qdcount-- > 0) {
  235.         char tname[MAXDNAME+1];
  236.         register int n, ttype, tclass;
  237.  
  238.         n = dn_expand(buf, eom, cp, tname, sizeof tname);
  239.         if (n < 0)
  240.             return (-1);
  241.         cp += n;
  242.         ttype = _getshort(cp); cp += INT16SZ;
  243.         tclass = _getshort(cp); cp += INT16SZ;
  244.         if (ttype == type &&
  245.             tclass == class &&
  246.             strcasecmp(tname, name) == 0)
  247.             return (1);
  248.     }
  249.     return (0);
  250. }
  251.  
  252. /* int
  253.  * res_queriesmatch(buf1, eom1, buf2, eom2)
  254.  *    is there a 1:1 mapping of (name,type,class)
  255.  *    in (buf1,eom1) and (buf2,eom2)?
  256.  * returns:
  257.  *    -1 : format error
  258.  *    0  : not a 1:1 mapping
  259.  *    >0 : is a 1:1 mapping
  260.  * author:
  261.  *    paul vixie, 29may94
  262.  */
  263. int
  264. res_queriesmatch(buf1, eom1, buf2, eom2)
  265.     const u_char *buf1, *eom1;
  266.     const u_char *buf2, *eom2;
  267. {
  268.     register const u_char *cp = buf1 + HFIXEDSZ;
  269.     int qdcount = ntohs(((HEADER*)buf1)->qdcount);
  270.  
  271.     if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
  272.         return (0);
  273.     while (qdcount-- > 0) {
  274.         char tname[MAXDNAME+1];
  275.         register int n, ttype, tclass;
  276.  
  277.         n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
  278.         if (n < 0)
  279.             return (-1);
  280.         cp += n;
  281.         ttype = _getshort(cp);    cp += INT16SZ;
  282.         tclass = _getshort(cp); cp += INT16SZ;
  283.         if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
  284.             return (0);
  285.     }
  286.     return (1);
  287. }
  288.  
  289. int
  290. res_send(buf, buflen, ans, anssiz)
  291.     const u_char *buf;
  292.     i